﻿/*-------------------------------------------------------------------------
* 命名空间: SiliconSelect.Common/CalcLevelHelper
* 类       名: CalcLevelHelper
* 功      能:  TD
* 时      间:  2023/9/8 14:21:47
* 版      本:  V1.0
* 作      者:  Fioman
* 格      言:  Talk is cheap,show me the code ^_^
*-------------------------------------------------------------------------*/
using SiliconSelect.Base;
using SiliconSelect.BLL;
using SiliconSelect.Models;
using SiliconSelect.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace SiliconSelect.Common
{
    public class CalcLevelHelper
    {

        /// <summary>
        /// 根据流水号去获取对应的等级以及其要去的料盒.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public static DataResult<int> GetLevelResByWaferId(string waferId)
        {
            DataResult<int> result = new DataResult<int>();
            string logInfo = "";
            try
            {
                if (!GlobalValues.WaferIdLevelDictionary.ContainsKey(waferId))
                {
                    // 如果没有这个流水号的对应的等级信息,就直接报错,并且保存为无等级.
                    // 如果是无等级,这里要记录无等级的原因
                    logInfo = $"计算流水号{waferId} 分选等级出错,出错原因: 无相关数据";
                    result.Data = 32; // 直流
                    result.Message = logInfo;
                }
                else
                {
                    // 先获取其等级字典
                    Dictionary<string, List<int>> levelMap = new Dictionary<string, List<int>>();
                    levelMap = GlobalValues.WaferIdLevelDictionary[waferId];
                    List<int> levelRes = GlobalValues.DetectedTypeNamesTotal.Keys.ToList();
                    foreach (var levelList in levelMap.Values)
                    {
                        if (levelList.Count > 0)
                        {
                            levelRes = levelRes.Intersect(levelList).ToList();
                        }
                    }

                    if (levelRes.Count > 0)
                    {
                        // 如果找到了,就取其中的最小值
                        result.Data = levelRes.Min();
                        if (result.Data < 1)
                        {
                            // 计算的等级小于1,也要预警
                            result.Message = $"{waferId} 流水号计算等级小于1,等级计算错误!";
                            return result;
                        }
                        result.State = true;
                    }
                    else
                    {
                        // 如果么有找到,就找并集的最大值
                        List<int> levelResError = new List<int>();
                        foreach (var levelList in levelMap.Values)
                        {
                            levelResError = levelResError.Union(levelList).ToList();
                        }
                        if (levelResError.Count > 0)
                        {
                            // 如果找到了,就找其中的最大值
                            result.Data = levelResError.Max();
                            result.State = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logInfo = ExceptionHelper.GetFullException(ex, MethodBase.GetCurrentMethod()!);
            }
            finally
            {
                if (logInfo != "")
                {
                    LogHelper.WriteLog(LogType.Exception, logInfo);
                }
                if (GlobalValues.WaferIdLevelDictionary.ContainsKey(waferId))
                {
                    GlobalValues.WaferIdLevelDictionary.Remove(waferId);
                }
            }
            return result;
        }
        public static int GetBoxesNumberByLevel(int calcLevel, ObservableCollection<BoxesStateModel> boxStateModelList)
        {
            int boxNumber = 19;
            try
            {
                // 首先是获取等级对应的料盒状态
                if (GlobalValues.LevelBoxMap.ContainsKey(calcLevel))
                {
                    // 1. 第一步先拿到料盒
                    List<int> boxesInto = GlobalValues.LevelBoxMap[calcLevel];
                    if (boxesInto.Count < 0)
                    {
                        LogHelper.WriteLog(LogType.Exception, $"等级{calcLevel} 对应的料盒数量为空,按直流处理!");
                        return boxNumber;
                    }
                    else if (boxesInto.Count > 0)
                    {


                        // 1. 第一梯度优先放入到正在使用的料盒中.
                        foreach (var box in boxStateModelList)
                        {
                            // 查看当前料盒状态.
                            if (boxesInto.Contains(box.BoxNumber))
                            {
                                if (box.DownBoxState == (int)BoxesStates.Using)
                                {
                                    box.DownCountPc++;
                                    return box.BoxNumber; // 如果这个料盒在使用,就放到这个料盒中去.
                                }
                                else if (box.UpBoxState == (int)(BoxesStates.Using))
                                {
                                    box.UpCountPc++;
                                    return box.BoxNumber; // 如果下层正在使用,就放到下层
                                }
                            }
                        }

                        // 2. 第二梯度,如果没有正在使用的料盒,就放到空闲料盒中去.
                        foreach (var box in boxStateModelList)
                        {
                            // 查看当前料盒状态.
                            if (boxesInto.Contains(box.BoxNumber))
                            {
                                if (box.DownBoxState == (int)BoxesStates.Free)
                                {
                                    box.DownCountPc++;
                                    box.DownBoxState = (int)(BoxesStates.Using);
                                    return box.BoxNumber; // 如果这个料盒在使用,就放到这个料盒中去.
                                }
                                else if (box.UpBoxState == (int)BoxesStates.Free)
                                {
                                    box.UpCountPc++;
                                    box.UpBoxState = (int)(BoxesStates.Using);
                                    return box.BoxNumber;
                                }
                            }
                        }
                        // 3. 如果走到这里就认为是所有的料盒都满了,就直流.
                        LogHelper.WriteLog(LogType.Exception, "料盒分选错误,没有找到合适料盒,返回19直流");

                        // 3. 第三梯度,没有正在使用的料盒,也没有空闲料盒,就直接直流.
                        LogHelper.WriteLog(LogType.Exception, $"等级{calcLevel} 映射的料盒全部已经满了,或者是锁定状态,直流");
                        return boxNumber;
                    }
                }
                else
                {
                    LogHelper.WriteLog(LogType.Exception, $"等级{calcLevel} 没有对应的等级料盒设定,按直流处理!");
                    return boxNumber;
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(LogType.Exception, ExceptionHelper.GetFullException(ex, MethodBase.GetCurrentMethod()!));
                return boxNumber;
            }
            return boxNumber;
        }
    }
}
